//----------------------------------------------------------------------------------------------
//	Filename:	Environment.h
//	Author:		Keith Bugeja
//	Date:		18/07/2012
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
#pragma once

// Illumina Environment
#include <System/EngineKernel.h>
#include <Scene/Environment.h>
#include <Scene/Scene.h>

#include <External/Compression/Compression.h>
#include <Scene/GeometricPrimitive.h>

// Factories
#include <Camera/CameraFactories.h>
#include <Device/DeviceFactories.h>
#include <Light/LightFactories.h>
#include <Space/SpaceFactories.h>
#include <Shape/ShapeFactories.h>
#include <Filter/FilterFactories.h>
#include <Sampler/SamplerFactories.h>
#include <Texture/TextureFactories.h>
#include <Material/MaterialFactories.h>
#include <Renderer/RendererFactories.h>
#include <Postproc/PostProcessFactories.h>
#include <Integrator/IntegratorFactories.h>
		 
#include <Staging/Acceleration.h>
#include <Sampler/SamplerDiagnostics.h>

//----------------------------------------------------------------------------------------------
using namespace Illumina::Core;
//----------------------------------------------------------------------------------------------

class SandboxEnvironment
{
protected:
	Environment *m_environment;
	EngineKernel *m_engineKernel;
	
		
public:
	//----------------------------------------------------------------------------------------------
	SandboxEnvironment(void)
		: m_environment(NULL)				
		, m_engineKernel(NULL)
	{  }

	//----------------------------------------------------------------------------------------------
	~SandboxEnvironment(void)
	{ 
	}

	Environment* GetEnvironment(void) { return m_environment; }
	EngineKernel* GetEngineKernel(void) { return m_engineKernel; }	

	//----------------------------------------------------------------------------------------------
	//----------------------------------------------------------------------------------------------
	bool Initialise(bool p_bVerbose)
	{
		//Initialise logger
		Logger * logger = new Logger();
		ConsoleLoggerSink * cls = new ConsoleLoggerSink();
		FileLoggerSink * fls0 = new FileLoggerSink("Output\\Logs\\Coverage.txt");	
		FileLoggerSink * fls1 = new FileLoggerSink("Output\\Logs\\Training.txt");
		FileLoggerSink * fls2 = new FileLoggerSink("Output\\Logs\\Ransac.txt");
		FileLoggerSink * fls3 = new FileLoggerSink("Output\\Logs\\Searching.txt");
		LoggerChannel * lc0 = new LoggerChannel("PCS");
		LoggerChannel * lc1 = new LoggerChannel("PointCloud");
		LoggerChannel * lc2 = new LoggerChannel("SegmentsGraph");
		LoggerChannel * lc3 = new LoggerChannel("StructureGraph");
		LoggerChannel * lc4 = new LoggerChannel("RANSAC");
		LoggerChannel * lc5 = new LoggerChannel("Training");
		LoggerChannel * lc6 = new LoggerChannel("Keyboard");
		LoggerChannel * lc7 = new LoggerChannel("Coverage");	
		LoggerChannel * lc8 = new LoggerChannel("Searching");

		lc0->AddSink(cls);
		lc1->AddSink(cls);
		lc2->AddSink(cls);
		lc3->AddSink(cls);
		lc4->AddSink(fls2);
		lc5->AddSink(fls1);
		lc6->AddSink(cls);
		lc7->AddSink(fls0);
		lc8->AddSink(fls3);

		logger->AddChannel("PCS", lc0, false);
		logger->AddChannel("PointCloud", lc1, false);
		logger->AddChannel("SegmentsGraph", lc2, false);
		logger->AddChannel("StructureGraph", lc3, false);
		logger->AddChannel("RANSAC", lc4, false);
		logger->AddChannel("Training", lc5, false);
		logger->AddChannel("Keyboard", lc6, false);
		logger->AddChannel("Coverage", lc7, false);
		logger->AddChannel("Searching", lc8, false);

		
		lc1->SetLoggingFilter(LL_InfoLevel);		//PointCloud
		lc4->SetLoggingFilter(LL_CriticalLevel);	//RANSAC
		lc5->SetLoggingFilter(LL_ErrorLevel);		//Training
		lc7->SetLoggingFilter(LL_WarningLevel);		//Coverage
		lc8->SetLoggingFilter(LL_ErrorLevel);		//Searching

		//----------------------------------------------------------------------------------------------
		// Engine Kernel
		//----------------------------------------------------------------------------------------------
		logger->Write("\nInitialising EngineKernel...", LL_Info);
		m_engineKernel = new EngineKernel();

		//----------------------------------------------------------------------------------------------
		// Sampler
		//----------------------------------------------------------------------------------------------
		logger->Write("Registering Samplers...", LL_Info);
		m_engineKernel->GetSamplerManager()->RegisterFactory("Random", new RandomSamplerFactory());
		m_engineKernel->GetSamplerManager()->RegisterFactory("Jitter", new JitterSamplerFactory());
		m_engineKernel->GetSamplerManager()->RegisterFactory("Multijitter", new MultijitterSamplerFactory());
		m_engineKernel->GetSamplerManager()->RegisterFactory("PrecomputedRandom", new PrecomputedRandomSamplerFactory());
		m_engineKernel->GetSamplerManager()->RegisterFactory("PrecomputedHalton", new PrecomputedHaltonSamplerFactory());
		m_engineKernel->GetSamplerManager()->RegisterFactory("PrecomputedSobol", new PrecomputedSobolSamplerFactory());

		//----------------------------------------------------------------------------------------------
		// Filter
		//----------------------------------------------------------------------------------------------
		logger->Write("Registering Filters...", LL_Info);
		m_engineKernel->GetFilterManager()->RegisterFactory("Box", new BoxFilterFactory());
		m_engineKernel->GetFilterManager()->RegisterFactory("Tent", new TentFilterFactory());

		//----------------------------------------------------------------------------------------------
		// Space
		//----------------------------------------------------------------------------------------------
		logger->Write("Registering Spaces...", LL_Info);
		m_engineKernel->GetSpaceManager()->RegisterFactory("Basic", new BasicSpaceFactory());
		m_engineKernel->GetSpaceManager()->RegisterFactory("BasicPCS", new BasicSpacePCSFactory());

		//----------------------------------------------------------------------------------------------
		// Integrator
		//----------------------------------------------------------------------------------------------
		logger->Write("Registering Integrators...", LL_Info);
		m_engineKernel->GetIntegratorManager()->RegisterFactory("PathTracing", new PathIntegratorFactory());
		m_engineKernel->GetIntegratorManager()->RegisterFactory("IGI", new IGIIntegratorFactory());
		m_engineKernel->GetIntegratorManager()->RegisterFactory("Whitted", new WhittedIntegratorFactory());
		m_engineKernel->GetIntegratorManager()->RegisterFactory("Depth", new DepthIntegratorFactory());
		//engineKernel.GetIntegratorManager()->RegisterFactory("Photon", new PhotonIntegratorFactory());
		//engineKernel.GetIntegratorManager()->RegisterFactory("Test", new TestIntegratorFactory());
		
		//----------------------------------------------------------------------------------------------
		// Post processing
		//----------------------------------------------------------------------------------------------
		logger->Write("Registering Post Processes...", LL_Info);
		m_engineKernel->GetPostProcessManager()->RegisterFactory("AutoTone", new AutoToneFactory());
		m_engineKernel->GetPostProcessManager()->RegisterFactory("DragoTone", new DragoToneFactory());
		m_engineKernel->GetPostProcessManager()->RegisterFactory("GlobalTone", new GlobalToneFactory());
		m_engineKernel->GetPostProcessManager()->RegisterFactory("Accumulation", new AccumulationBufferFactory());
		m_engineKernel->GetPostProcessManager()->RegisterFactory("Discontinuity", new DiscontinuityBufferFactory());
		m_engineKernel->GetPostProcessManager()->RegisterFactory("Reconstruction", new ReconstructionBufferFactory());

		//----------------------------------------------------------------------------------------------
		// Renderer
		//----------------------------------------------------------------------------------------------
		logger->Write("Registering Renderers...", LL_Info);
		m_engineKernel->GetRendererManager()->RegisterFactory("Basic", new BasicRendererFactory());
		m_engineKernel->GetRendererManager()->RegisterFactory("Multipass", new MultipassRendererFactory());
		m_engineKernel->GetRendererManager()->RegisterFactory("Multithreaded", new MultithreadedRendererFactory());
		m_engineKernel->GetRendererManager()->RegisterFactory("Distributed", new DistributedRendererFactory());
		m_engineKernel->GetRendererManager()->RegisterFactory("TimeConstrained", new TimeConstrainedRendererFactory());

		//----------------------------------------------------------------------------------------------
		// Device
		//----------------------------------------------------------------------------------------------
		logger->Write("Registering Devices...", LL_Info);
		m_engineKernel->GetDeviceManager()->RegisterFactory("Display", new DisplayDeviceFactory());
		m_engineKernel->GetDeviceManager()->RegisterFactory("Image", new ImageDeviceFactory());
		m_engineKernel->GetDeviceManager()->RegisterFactory("Video", new VideoDeviceFactory());
		m_engineKernel->GetDeviceManager()->RegisterFactory("RTP", new RTPDeviceFactory());
		m_engineKernel->GetDeviceManager()->RegisterFactory("BufferedImage", new BufferedImageDeviceFactory());

		//----------------------------------------------------------------------------------------------
		// Cameras
		//----------------------------------------------------------------------------------------------
		logger->Write("Registering Cameras...", LL_Info);
		m_engineKernel->GetCameraManager()->RegisterFactory("Perspective", new PerspectiveCameraFactory());
		m_engineKernel->GetCameraManager()->RegisterFactory("ThinLens", new ThinLensCameraFactory());

		//----------------------------------------------------------------------------------------------
		// Lights
		//----------------------------------------------------------------------------------------------
		logger->Write("Registering Lights...", LL_Info);
		m_engineKernel->GetLightManager()->RegisterFactory("Point", new PointLightFactory());
		m_engineKernel->GetLightManager()->RegisterFactory("DiffuseArea", new DiffuseAreaLightFactory());
		m_engineKernel->GetLightManager()->RegisterFactory("InfiniteArea", new InfiniteAreaLightFactory());

		//----------------------------------------------------------------------------------------------
		// Shapes
		//----------------------------------------------------------------------------------------------
		logger->Write("Registering Shapes...", LL_Info);
		m_engineKernel->GetShapeManager()->RegisterFactory("PersistentMesh", new PersistentMeshShapeFactory());
		m_engineKernel->GetShapeManager()->RegisterFactory("KDTreeMesh", new KDTreeMeshShapeFactory());
		m_engineKernel->GetShapeManager()->RegisterFactory("BVHMesh", new BVHMeshShapeFactory());
		m_engineKernel->GetShapeManager()->RegisterFactory("Quad", new QuadMeshShapeFactory());
		m_engineKernel->GetShapeManager()->RegisterFactory("Triangle", new TriangleShapeFactory());
		m_engineKernel->GetShapeManager()->RegisterFactory("Sphere", new SphereShapeFactory());
		m_engineKernel->GetShapeManager()->RegisterFactory("KDTreePointCloud", new PointCloudShapeFactory());

		//----------------------------------------------------------------------------------------------
		// Textures
		//----------------------------------------------------------------------------------------------
		logger->Write("Registering Textures...", LL_Info);
		m_engineKernel->GetTextureManager()->RegisterFactory("MappedFile", new MemoryMappedTextureFactory());
		m_engineKernel->GetTextureManager()->RegisterFactory("Image", new ImageTextureFactory());
		m_engineKernel->GetTextureManager()->RegisterFactory("Noise", new NoiseTextureFactory());
		m_engineKernel->GetTextureManager()->RegisterFactory("Marble", new MarbleTextureFactory());

		//----------------------------------------------------------------------------------------------
		// Materials
		//----------------------------------------------------------------------------------------------
		logger->Write("Registering Materials...", LL_Info);
		m_engineKernel->GetMaterialManager()->RegisterFactory("Matte", new MatteMaterialFactory());
		m_engineKernel->GetMaterialManager()->RegisterFactory("Mirror", new MirrorMaterialFactory());
		m_engineKernel->GetMaterialManager()->RegisterFactory("Glass", new GlassMaterialFactory());
		m_engineKernel->GetMaterialManager()->RegisterFactory("Group", new MaterialGroupFactory());
	
		//----------------------------------------------------------------------------------------------
		// Environment
		//----------------------------------------------------------------------------------------------
		logger->Write("Initialising Environment...", LL_Info);
		m_environment = new Environment(m_engineKernel);
		m_environment->SetLogger(logger);
		return true;
	}

	//----------------------------------------------------------------------------------------------
	//----------------------------------------------------------------------------------------------
	bool Shutdown(bool p_bVerbose)
	{
		//----------------------------------------------------------------------------------------------
		// Environment
		//----------------------------------------------------------------------------------------------
		m_environment->GetLogger()->Write("Shutting down Environment...", LL_Info);
		Safe_Delete(m_environment);

		//----------------------------------------------------------------------------------------------
		// EngineKernel
		//----------------------------------------------------------------------------------------------
		if (m_engineKernel) 
		{
			//----------------------------------------------------------------------------------------------
			// Sampler
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Freeing and unregistering Samplers...", LL_Info);
			delete m_engineKernel->GetSamplerManager()->RequestFactory("Random");
			delete m_engineKernel->GetSamplerManager()->RequestFactory("Jitter");
			delete m_engineKernel->GetSamplerManager()->RequestFactory("Multijitter");
			delete m_engineKernel->GetSamplerManager()->RequestFactory("PrecomputedRandom");
			delete m_engineKernel->GetSamplerManager()->RequestFactory("PrecomputedHalton");
			delete m_engineKernel->GetSamplerManager()->RequestFactory("PrecomputedSobol");

			m_engineKernel->GetSamplerManager()->UnregisterFactory("Random");
			m_engineKernel->GetSamplerManager()->UnregisterFactory("Jitter");
			m_engineKernel->GetSamplerManager()->UnregisterFactory("Multijitter");
			m_engineKernel->GetSamplerManager()->UnregisterFactory("PrecomputedRandom");
			m_engineKernel->GetSamplerManager()->UnregisterFactory("PrecomputedHalton");
			m_engineKernel->GetSamplerManager()->UnregisterFactory("PrecomputedSobol");

			//----------------------------------------------------------------------------------------------
			// Filter
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Freeing and unregistering Filters...", LL_Info);
			delete m_engineKernel->GetFilterManager()->RequestFactory("Box");
			delete m_engineKernel->GetFilterManager()->RequestFactory("Tent");

			m_engineKernel->GetFilterManager()->UnregisterFactory("Box");
			m_engineKernel->GetFilterManager()->UnregisterFactory("Tent");

			//----------------------------------------------------------------------------------------------
			// Space
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Freeing and unregistering Spaces...", LL_Info);
			delete m_engineKernel->GetSpaceManager()->RequestFactory("Basic");
			delete m_engineKernel->GetSpaceManager()->RequestFactory("BasicPCS");
			m_engineKernel->GetSpaceManager()->UnregisterFactory("Basic");			
			m_engineKernel->GetSpaceManager()->UnregisterFactory("BasicPCS");

			//----------------------------------------------------------------------------------------------
			// Integrator
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Freeing and unregistering Integrators...", LL_Info);
			delete m_engineKernel->GetIntegratorManager()->RequestFactory("PathTracing");
			delete m_engineKernel->GetIntegratorManager()->RequestFactory("IGI");
			delete m_engineKernel->GetIntegratorManager()->RequestFactory("Whitted");
			delete m_engineKernel->GetIntegratorManager()->RequestFactory("Depth");
			//delete m_engineKernel->GetIntegratorManager()->RequestFactory("Photon");
			//delete m_engineKernel->GetIntegratorManager()->RequestFactory("Test");

			m_engineKernel->GetIntegratorManager()->UnregisterFactory("PathTracing");
			m_engineKernel->GetIntegratorManager()->UnregisterFactory("IGI");
			m_engineKernel->GetIntegratorManager()->UnregisterFactory("Whitted");
			m_engineKernel->GetIntegratorManager()->UnregisterFactory("Depth");
			//m_engineKernel->GetIntegratorManager()->UnregisterFactory("Photon");
			//m_engineKernel->GetIntegratorManager()->UnregisterFactory("Test");

			//----------------------------------------------------------------------------------------------
			// Renderer
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Freeing and unregistering Renderers...", LL_Info);
			delete m_engineKernel->GetRendererManager()->RequestFactory("Basic");
			delete m_engineKernel->GetRendererManager()->RequestFactory("Multipass");
			delete m_engineKernel->GetRendererManager()->RequestFactory("Multithreaded");
			delete m_engineKernel->GetRendererManager()->RequestFactory("Distributed");
			delete m_engineKernel->GetRendererManager()->RequestFactory("TimeConstrained");

			m_engineKernel->GetRendererManager()->UnregisterFactory("Basic");
			m_engineKernel->GetRendererManager()->UnregisterFactory("Multipass");
			m_engineKernel->GetRendererManager()->UnregisterFactory("Multithreaded");
			m_engineKernel->GetRendererManager()->UnregisterFactory("Distributed");
			m_engineKernel->GetRendererManager()->UnregisterFactory("TimeConstrained");

			//----------------------------------------------------------------------------------------------
			// Device
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Freeing and unregistering Devices...", LL_Info);
			delete m_engineKernel->GetDeviceManager()->RequestFactory("Display");
			delete m_engineKernel->GetDeviceManager()->RequestFactory("Image");
			delete m_engineKernel->GetDeviceManager()->RequestFactory("Video");
			delete m_engineKernel->GetDeviceManager()->RequestFactory("RTP");
			delete m_engineKernel->GetDeviceManager()->RequestFactory("BufferedImage");

			m_engineKernel->GetDeviceManager()->UnregisterFactory("Display");
			m_engineKernel->GetDeviceManager()->UnregisterFactory("Image");
			m_engineKernel->GetDeviceManager()->UnregisterFactory("Video");
			m_engineKernel->GetDeviceManager()->UnregisterFactory("RTP");
			m_engineKernel->GetDeviceManager()->UnregisterFactory("BufferedImage");

			//----------------------------------------------------------------------------------------------
			// Cameras
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Freeing and unregistering Cameras...", LL_Info);
			delete m_engineKernel->GetCameraManager()->RequestFactory("Perspective");
			delete m_engineKernel->GetCameraManager()->RequestFactory("ThinLens");

			m_engineKernel->GetCameraManager()->UnregisterFactory("Perspective");
			m_engineKernel->GetCameraManager()->UnregisterFactory("ThinLens");

			//----------------------------------------------------------------------------------------------
			// Lights
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Freeing and unregistering Lights...", LL_Info);
			delete m_engineKernel->GetLightManager()->RequestFactory("Point");
			delete m_engineKernel->GetLightManager()->RequestFactory("DiffuseArea");
			delete m_engineKernel->GetLightManager()->RequestFactory("InfiniteArea");

			m_engineKernel->GetLightManager()->UnregisterFactory("Point");
			m_engineKernel->GetLightManager()->UnregisterFactory("DiffuseArea");
			m_engineKernel->GetLightManager()->UnregisterFactory("InfiniteArea");

			//----------------------------------------------------------------------------------------------
			// Shapes
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Freeing and unregistering Shapes...", LL_Info);
			delete m_engineKernel->GetShapeManager()->RequestFactory("PersistentMesh");
			delete m_engineKernel->GetShapeManager()->RequestFactory("KDTreeMesh");
			delete m_engineKernel->GetShapeManager()->RequestFactory("BVHMesh");
			delete m_engineKernel->GetShapeManager()->RequestFactory("Quad");
			delete m_engineKernel->GetShapeManager()->RequestFactory("Triangle");
			delete m_engineKernel->GetShapeManager()->RequestFactory("Sphere");
			delete m_engineKernel->GetShapeManager()->RequestFactory("PointCloud");
			

			m_engineKernel->GetShapeManager()->UnregisterFactory("PersistentMesh");
			m_engineKernel->GetShapeManager()->UnregisterFactory("KDTreeMesh");
			m_engineKernel->GetShapeManager()->UnregisterFactory("BVHMesh");
			m_engineKernel->GetShapeManager()->UnregisterFactory("Quad");
			m_engineKernel->GetShapeManager()->UnregisterFactory("Triangle");
			m_engineKernel->GetShapeManager()->UnregisterFactory("Sphere");
			m_engineKernel->GetShapeManager()->UnregisterFactory("PointCloud");

			//----------------------------------------------------------------------------------------------
			// Textures
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Freeing and unregistering Textures...", LL_Info);
			delete m_engineKernel->GetTextureManager()->RequestFactory("MappedFile");
			delete m_engineKernel->GetTextureManager()->RequestFactory("Image");
			delete m_engineKernel->GetTextureManager()->RequestFactory("Noise");
			delete m_engineKernel->GetTextureManager()->RequestFactory("Marble");

			m_engineKernel->GetTextureManager()->UnregisterFactory("MappedFile");
			m_engineKernel->GetTextureManager()->UnregisterFactory("Image");
			m_engineKernel->GetTextureManager()->UnregisterFactory("Noise");
			m_engineKernel->GetTextureManager()->UnregisterFactory("Marble");

			//----------------------------------------------------------------------------------------------
			// Materials
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Freeing and unregistering Materials...", LL_Info);
			delete m_engineKernel->GetMaterialManager()->RequestFactory("Matte");
			delete m_engineKernel->GetMaterialManager()->RequestFactory("Mirror");
			delete m_engineKernel->GetMaterialManager()->RequestFactory("Glass");
			delete m_engineKernel->GetMaterialManager()->RequestFactory("Group");

			m_engineKernel->GetMaterialManager()->UnregisterFactory("Matte");
			m_engineKernel->GetMaterialManager()->UnregisterFactory("Mirror");
			m_engineKernel->GetMaterialManager()->UnregisterFactory("Glass");
			m_engineKernel->GetMaterialManager()->UnregisterFactory("Group");

			//----------------------------------------------------------------------------------------------
			// Post processing
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Freeing and unregistering Post Processes...", LL_Info);
			delete m_engineKernel->GetPostProcessManager()->RequestFactory("AutoTone");
			delete m_engineKernel->GetPostProcessManager()->RequestFactory("DragoTone");
			delete m_engineKernel->GetPostProcessManager()->RequestFactory("GlobalTone");
			delete m_engineKernel->GetPostProcessManager()->RequestFactory("Accumulation");
			delete m_engineKernel->GetPostProcessManager()->RequestFactory("Discontinuity");
			delete m_engineKernel->GetPostProcessManager()->RequestFactory("Reconstruction");

			m_engineKernel->GetPostProcessManager()->UnregisterFactory("AutoTone");
			m_engineKernel->GetPostProcessManager()->UnregisterFactory("DragoTone");
			m_engineKernel->GetPostProcessManager()->UnregisterFactory("GlobalTone");
			m_engineKernel->GetPostProcessManager()->UnregisterFactory("Accumulation");
			m_engineKernel->GetPostProcessManager()->UnregisterFactory("Discontinuity");
			m_engineKernel->GetPostProcessManager()->UnregisterFactory("Reconstruction");
					
			//----------------------------------------------------------------------------------------------
			// Engine Kernel
			//----------------------------------------------------------------------------------------------
			m_environment->GetLogger()->Write("Shutting down Engine Kernel...", LL_Info);
			Safe_Delete(m_engineKernel);
		}
				
		return true;
	}

	//----------------------------------------------------------------------------------------------
	//----------------------------------------------------------------------------------------------
	bool LoadScene(const std::string &p_strScript, bool p_bVerbose)
	{		
		if (m_environment == NULL)
			return false;

		// Load environment script
		m_environment->GetLogger()->Write("Loading Environment script...", LL_Info);
	
		if (!m_environment->Load(p_strScript))
		{
			m_environment->GetLogger()->Write("Unable to load Environment script.", LL_Critical);
			return false;
		}	

		// Initialise integrator and renderer
		m_environment->GetIntegrator()->Initialise(m_environment->GetScene(), m_environment->GetCamera());
		m_environment->GetRenderer()->Initialise();

		return true;
	}
};
